package com.magnificent.panda.correlation;

import com.magnificent.panda.model.entity.FlowEvent;

/**
 * User: Babanin
 * Date: 13.03.2010
 * Time: 9:56:02
 */
public class IvashenkoFlowsCorrelationFunction implements IntervalCorrelationFunction {
    private int minCount;    //  minimum of first and second flow length
    private double deltaTau;    //  interval of discretization
    private int countOfFirstStream;  //  length of second stream
    private int countOfSecondStream;  //  length of second stream
    private int countOfCorrelationFunction;  //  length of correlation array

    private FlowEvent mainStream[];   //  first flow
    private FlowEvent secondStream[][];  //  second flow
    private double correlationFunctionResult[];  //  result of correlation function

    public double[] calculateCorrelation(FlowEvent mainStream[], FlowEvent secondaryStream[][],
                                         int countOfCorrelationFunction, double deltaTau, boolean useConnectivity) {
        // Initialize
        this.deltaTau = deltaTau;
        this.mainStream = mainStream;
        this.secondStream = secondaryStream;

        countOfFirstStream = mainStream.length;
        countOfSecondStream = secondaryStream.length;
        minCount = Math.min(mainStream.length, secondaryStream.length);

        correlationFunctionResult = new double[countOfCorrelationFunction];

        for (int j = 0; j < countOfCorrelationFunction; j++) {

            int sum = 0;
            for (int i = 0; i < secondaryStream.length; i++) {
                for (int k = 0; k < countOfFirstStream; k++) {
                    for (int m = 0; m < secondaryStream[i].length; m++) {
                        sum += calcStateIndicator(j, i, k, m, useConnectivity);
                    }
                }
            }

            correlationFunctionResult[j] = sum;
        }


        return correlationFunctionResult;
    }

    public int calcStateIndicator(int j, int i, int k, int m, boolean useConnectivity) {
        if (useConnectivity && (secondStream[i][m].getId() != mainStream[k].getId())) {
            return 0;
        } 

        try {
            int stateIndicator = (int) Math.floor(Math.abs(secondStream[i][m].getValue() - mainStream[k].getValue()) / deltaTau + 0.5);

            if (stateIndicator == j) {
                return 1;
            } else {
                return 0;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            return 0;
        }
    }

    public double[] calculateCorrelation(FlowEvent[] firstStream, FlowEvent[] secondStream, int correlationSize, double deltaTau) {
        return null;
    }

    public int calcStateIndicator(int j, int i, int s) {
        return 0;
    }

    public boolean isMultiFlowsSupported() {
        return true;
    }

    @Override
    public String toString() {
        return "ИКФ №4";
    }
}
  /* converted to utf8 */